package ar.com.pragmatia.lanacion.data;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import org.apache.http.NameValuePair;

public class HttpFileUploader implements Runnable {

	private URL connectURL;
	private List<NameValuePair> postVars;
	private List<PostFile> postFiles;
	// private String fileName;
	FileInputStream fileInputStream = null;
	String responseMessage;
	String lineEnd = "\r\n";
	String twoHyphens = "--";
	String boundary = "#{617cac4d3ef37f90518c8b0ce}#";

	// public HttpFileUploader(String urlString, String params, String fileName)
	// {
	// try {
	// connectURL = new URL(urlString);
	// } catch (Exception ex) {
	// Log.i("URL FORMATION", "MALFORMATED URL");
	// }
	// this.fileName = fileName;
	//
	// }

	public boolean addFile(FileInputStream newFileStream, String fileName,
			String postVarName) {
		PostFile newFile = new PostFile(newFileStream, fileName, postVarName);
		return postFiles.add(newFile);
	}

	public boolean addFile(String newFileString, String fileName,
			String postVarName) throws FileNotFoundException {
		FileInputStream newFileStream = new FileInputStream(newFileString);
		return addFile(newFileStream, fileName, postVarName);
	}

	public boolean addFile(String newFileString, String postVarName)
			throws FileNotFoundException {
		FileInputStream newFileStream = new FileInputStream(newFileString);
		String fileName = (new File(newFileString)).getName();
		return addFile(newFileStream, fileName, postVarName);
	}

	public boolean addVar(NameValuePair newVar) {
		return postVars.add(newVar);
	}

	public HttpFileUploader(String url) throws MalformedURLException {
		connectURL = new URL(url);
		postVars = new ArrayList<NameValuePair>();
		postFiles = new ArrayList<PostFile>();
	}

	// public void doStart(FileInputStream stream) {
	// fileInputStream = stream;
	// thirdTry();
	// }

	public String excecute() throws IOException {
		// Start the connection
		HttpURLConnection conn = (HttpURLConnection) connectURL
				.openConnection();
		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setUseCaches(false);
		// Set method and headers
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Connection", "Keep-Alive");
		conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="
				+ boundary);
		// conn.connect();
		DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
		// Write post vars
		if (!postVars.isEmpty()) {
			writePostVars(dos);
		}
		// Write files
		if (!postFiles.isEmpty()) {
			writePostFiles(dos);
		}
		// Finish post data
		dos.writeBytes(lineEnd);
		dos.writeBytes(twoHyphens + boundary + lineEnd);
		dos.flush();
		dos.close();
		// Get the response
		InputStream is = conn.getInputStream();
		int ch;
		StringBuffer b = new StringBuffer();
		while ((ch = is.read()) != -1) {
			b.append((char) ch);
		}
		String response = b.toString();
		is.close();
		setResponseMessage(response);
		return response;
	}

	private boolean writePostVars(DataOutputStream dos) throws IOException {
		ListIterator<NameValuePair> iterator = postVars.listIterator();
		while (iterator.hasNext()) {
			NameValuePair postVar = iterator.next();
			if (postVar == null) {
				return false;
			}
			dos.writeBytes(twoHyphens + boundary + lineEnd);
			dos.writeBytes("Content-Disposition: form-data; name=\""
					+ postVar.getName() + "\"" + lineEnd);
			dos.writeBytes(lineEnd);
			dos.writeBytes(postVar.getValue());
			dos.writeBytes(lineEnd);
		}
		return true;
	}

	private boolean writePostFiles(DataOutputStream dos) throws IOException {
		ListIterator<PostFile> iterator = postFiles.listIterator();
		while (iterator.hasNext()) {
			PostFile postFile = iterator.next();
			if (postFile == null) {
				return false;
			}
			dos.writeBytes(twoHyphens + boundary + lineEnd);
			dos.writeBytes("Content-Disposition: form-data; name=\""
					+ postFile.getPostVarName() + "\";filename=\""
					+ postFile.getFileName() + "\"" + lineEnd);
			dos.writeBytes(lineEnd);

			int bytesAvailable = postFile.getFileStream().available();
			int maxBufferSize = 1024;
			int bufferSize = Math.min(bytesAvailable, maxBufferSize);
			byte[] buffer = new byte[bufferSize];

			int bytesRead = postFile.getFileStream()
					.read(buffer, 0, bufferSize);

			while (bytesRead > 0) {
				dos.write(buffer, 0, bufferSize);
				bytesAvailable = postFile.getFileStream().available();
				bufferSize = Math.min(bytesAvailable, maxBufferSize);
				bytesRead = postFile.getFileStream()
						.read(buffer, 0, bufferSize);
			}
			dos.writeBytes(lineEnd);
			postFile.getFileStream().close();
		}
		return true;
	}

	// private void thirdTry() {
	// String exsistingFileName = fileName;
	//
	// String Tag = "3rd";
	// try {
	//
	// HttpURLConnection conn = (HttpURLConnection) connectURL
	// .openConnection();
	//
	// conn.setDoInput(true);
	// conn.setDoOutput(true);
	// conn.setUseCaches(false);
	//
	// conn.setRequestMethod("POST");
	//
	// conn.setRequestProperty("Connection", "Keep-Alive");
	//
	// conn.setRequestProperty("Content-Type",
	// "multipart/form-data;boundary=" + boundary);
	//
	// DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
	//
	// dos.writeBytes(twoHyphens + boundary + lineEnd);
	// dos.writeBytes("Content-Disposition: form-data; name=\"unavar\""
	// + lineEnd);
	// dos.writeBytes(lineEnd);
	// dos.writeBytes("asjdhgajsgdhjashd" + lineEnd);
	//
	// dos.writeBytes(twoHyphens + boundary + lineEnd);
	// dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
	// + exsistingFileName + "\"" + lineEnd);
	// dos.writeBytes(lineEnd);
	//
	// int bytesAvailable = fileInputStream.available();
	// int maxBufferSize = 1024;
	// int bufferSize = Math.min(bytesAvailable, maxBufferSize);
	// byte[] buffer = new byte[bufferSize];
	//
	// int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
	//
	// while (bytesRead > 0) {
	// dos.write(buffer, 0, bufferSize);
	// bytesAvailable = fileInputStream.available();
	// bufferSize = Math.min(bytesAvailable, maxBufferSize);
	// bytesRead = fileInputStream.read(buffer, 0, bufferSize);
	// }
	// dos.writeBytes(lineEnd);
	// dos.writeBytes(twoHyphens + boundary + lineEnd);
	//
	// fileInputStream.close();
	// dos.flush();
	//
	// String response = conn.getResponseMessage();
	//
	// // InputStream is = conn.getInputStream();
	// // int ch;
	// //
	// // StringBuffer b = new StringBuffer();
	// // while ((ch = is.read()) != -1) {
	// // b.append((char) ch);
	// // }
	// // String s = b.toString();
	// Log.i("Response", response);
	// dos.close();
	//
	// } catch (MalformedURLException ex) {
	// Log.e(Tag, "error: " + ex.getMessage(), ex);
	// }
	//
	// catch (IOException ioe) {
	// Log.e(Tag, "error: " + ioe.getMessage(), ioe);
	// }
	// }

	public void run() {
		// Run as Thread
		try {
			excecute();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public String getResponseMessage() {
		return responseMessage;
	}

	public void setResponseMessage(String responseMessage) {
		this.responseMessage = responseMessage;
	}

	private class PostFile {

		private String fileName;
		private String postVarName;
		private FileInputStream fileStream;

		public PostFile(FileInputStream fileStream, String fileName,
				String postVarName) {
			this.fileStream = fileStream;
			this.fileName = fileName;
			this.postVarName = postVarName;
		}

		public String getFileName() {
			return fileName;
		}

		public FileInputStream getFileStream() {
			return fileStream;
		}

		public String getPostVarName() {
			return postVarName;
		}

	}

}
